feat(sight): show LLM latency metrics in agent sessions - #2586
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fbe5f7ae6d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
chengshuyi
left a comment
There was a problem hiding this comment.
Review 反馈
感谢这个 PR!代码质量不错——stale request guard、nullable 指标降级为 —、独立 loading 状态等设计都很合理。
设计建议:面板放置位置
建议将 latency metrics 面板从「会话列表」(/sessions) 移到「Agent 看板」(/health) 页面。
理由:
- 语义对齐 — Agent 看板已经在做 per-agent 运行状态监控(健康/卡顿/崩溃/离线),延迟指标(TTFT/TPS/TPOT/E2E)本质上就是 Agent 的性能 vital signs,和 CPU 利用率是同一类信息——看的是"这个 agent 当前工作状态如何"。
- 粒度匹配 —
/api/metrics/latency返回的是 per-agent 聚合数据(GROUP BY agent_name),不是 per-session 的。放在会话列表里,用户需要在"会话明细"和"聚合指标"之间做心理切换。 - 现有结构天然适配 — AgentHealthPage 的 AgentCard 已按 agent 分卡片展示,可以在卡片上追加 mini 指标行(如
TTFT p50: 320ms · TPS p50: 42 t/s),或在卡片网格下方加一个"延迟百分位"表格 section。 - 会话列表保持纯粹 — AgentSessionsPage 的核心职责是"找到某个会话 → 点进去看轨迹",聚合面板会分散注意力。
其他 minor findings
- 合并顺序:#2590 尚未合并,需确保 #2590 → #2586 的顺序,否则 agent filter 大小写不匹配会返回空数据。
- i18n 位置:zh-CN 的 latency 键被插入到对象最顶部(
app.title之前),建议移到与 en-US 相同的相对位置,方便对照维护。 - unit 前导空格:
unit=" tokens/s"与其他unit="ms"不一致,建议统一在组件内部加空格分隔。 - 刷新按钮:
disabled={loading}可考虑加上|| latencyLoading。
以上 minor 项不阻塞,主要想讨论的是面板位置的设计方向。
fbe5f7a to
481a579
Compare
感谢 Review,已经按建议调整了这一版: |
chengshuyi
left a comment
There was a problem hiding this comment.
二轮 Review:延迟指标应嵌入 AgentCard 内部
感谢快速响应上一轮反馈!面板迁移到 /health、i18n 对齐、unit 统一等都已确认 OK。
设计调整:指标嵌入卡片
当前实现是一个独立的 LatencyMetricsSection 表格,放在 AgentStatusSection 和 InterruptionSection 之间。希望改为将延迟指标嵌入到每个 AgentCard 内部,理由:
- 一一对应 — 看板的核心交互单元是卡片(per-agent),指标跟着卡片走,用户不需要在"卡片网格"和"下方表格"之间做视觉跳转再按 agent name 匹配。
- 信息内聚 — 卡片已经在展示
latency_ms(健康探活延迟),LLM 延迟百分位(TTFT/TPS/TPOT/E2E)是同一维度的延伸,放在一起更自然。 - 空间效率 — 独立表格在 agent 数量少(1-3 个,最常见场景)时显得空旷,嵌入卡片后布局更紧凑。
建议实现方式
在 AgentCard 的 PID/状态行下方追加一行 compact 指标:
// AgentCard 内部,PID 行之后
{latency && (
<div className="mt-1.5 pt-1.5 border-t border-gray-100 text-[11px] text-gray-500 flex flex-wrap gap-x-3 gap-y-0.5">
<span>TTFT <b className="text-gray-700">{fmt(latency.ttft_ms?.p50)}ms</b></span>
<span>TPS <b className="text-gray-700">{fmt(latency.tps?.p50)} t/s</b></span>
<span>E2E <b className="text-gray-700">{fmt(latency.e2e?.p50)}ms</b></span>
</div>
)}要点:
- 默认只展示 p50(卡片空间有限),p95/p99 可以通过 tooltip 或 hover 展示
- 无数据的指标显示
—,整行无数据时不渲染 - 时间范围选择器(24h/7d/30d)提升到
AgentStatusSection的标题行右侧,作为全局控制 fetchLatencyMetrics返回的是 per-agent 聚合,按agent_name匹配分发到各卡片即可
保留的部分
apiClient.ts的接口定义和fetchLatencyMetrics函数 ✅ 无需改动- 回归测试 ✅ 无需改动
- i18n keys ✅ 无需改动(可能需微调,如去掉
latency.agent列头键) - stale request guard / 独立 loading 状态 ✅ 逻辑保留,只是渲染位置从独立 section 移到 section 内部
其他
- codex bot 的 casing thread 可以 resolve 了(#2590 已合并)
- LanguageSwitcher 重写质量不错,LGTM
感谢二轮 Review,我已经按建议完成了调整: |
chengshuyi
left a comment
There was a problem hiding this comment.
三轮 Review:LGTM ✅
二轮反馈完整落地:
- ✅ Latency 指标嵌入 AgentCard 内部,p50 内联展示,p95/p99 通过 tooltip 查看
- ✅ 24h / 7d / 30d 时间范围选择器提升到 Agent Status 标题栏右侧
- ✅ Agent 名称关联使用 lowercase canonical key 做大小写不敏感匹配
- ✅ i18n keys 位置对齐(en-US 与 zh-CN 都在 nav.settings 之后)
- ✅ unit spacing 统一(
formatMetricP50内部加空格) - ✅ stale request guard / 独立 loading/error 状态保留
- ✅ 整行无数据时不渲染(
items.some(item => item.metric !== null))
整体设计现在很自然:卡片即 Agent 的 vital signs 面板,TTFT/TPS/TPOT/E2E 与健康探活 latency_ms 在同一视觉单元,符合"看板"语义。
几个非阻塞的小观察(仅供参考,不必处理)
-
latencyForAgent的 defensive return — 当同一 canonical key 出现多条 summary 时返回undefined。#2590 合并后后端用COLLATE NOCASE已不会返回 casing 变体,所以这是纯防御逻辑。万一未来后端回归,UI 会静默丢数据;如果想更可观察,可以在多条时取第一条 +console.warn,或在 tooltip 里提示。当前实现也 OK,保守安全。 -
latencyByAgentMap 未 memoize — 每次 render 重建。Agent 数量通常 1–5 个,性能可忽略;如果将来要扩展,可以包一层useMemo([latencyMetrics])。 -
LanguageSwitcher 重写 — 自定义 dropdown 比 native select 多了 ~90 行,但换来了 in-page 切换体验。a11y 处理到位(
aria-haspopup/aria-expanded/aria-controls/role="menuitemradio"/aria-checked/ Escape + outside-click 关闭),实现质量不错。 -
commit history — 包含一个 merge commit(
1948d48)和多个 fixup,合并时建议 squash 保持 main 整洁(按仓库惯例即可)。
验证
- 12 个 API client tests + 4 个 i18n tests 通过
- typecheck / build / build:embed 通过
- 手动验证覆盖 24h/7d/30d 切换、中英文切换、nullable 指标降级
Approve. 等 CI 绿了就可以合了。感谢这一系列高质量的迭代!


Summary
Completes the AgentSight latency metrics UI part of #2339, following the backend/API work merged in #2578.
This adds per-agent LLM latency and throughput percentiles to the Agent Health page using the existing
/api/metrics/latencyendpoint. The Agent Sessions page remains focused on session history.Refs #2339
Changes
fetchLatencyMetrics()for/api/metrics/latency—instead of0The current branch is based on main after the Agent-name casing follow-up was merged; no frontend casing workaround is included.
Validation
npm run test:api-client— 12 passednpm run test:i18n— 4 passednpm run typechecknpm run buildnpm run build:embedgit diff --checkAll passed. Builds emit only the existing bundle-size warning.
Manual UI verification
TTFT/TPS/TPOTshown as—, while E2E remains available)Scope
This PR is frontend-only. It does not change backend metric semantics, Rust code, eBPF, schema, or add the cleanup changes from #2583.
Screenshot